package middleware

import (
	"gf_blog_admin/internal/service"
	"gf_blog_admin/utility/errors"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/net/ghttp"
	"golang.org/x/time/rate"
	"net/http"
)

type sMiddleware struct{}

func init() {
	service.RegisterMiddleware(New())
}

func New() *sMiddleware {
	return &sMiddleware{}
}

// Ctx 自定义上下文对象
func (s *sMiddleware) Ctx(r *ghttp.Request) {
	r.Middleware.Next()
}

// CORS 自定义跨域处理
func (s *sMiddleware) CORS(r *ghttp.Request) {
	corsOptions := r.Response.DefaultCORSOptions()
	// corsOptions.AllowDomain = []string{"baidu.com"}
	r.Response.CORS(corsOptions)
	r.Middleware.Next()
}

// Limiter 限流中间件
func (s *sMiddleware) Limiter(rps int, burst int) func(r *ghttp.Request) {
	return func(r *ghttp.Request) {
		if !rate.NewLimiter(rate.Limit(burst), rps).Allow() {
			r.SetError(gerror.NewCode(errors.CodeTooManyRequest))
			return
		}
		r.Middleware.Next()
	}
}

// ResponseHandler 自定义响应处理
func (s *sMiddleware) ResponseHandler(r *ghttp.Request) {
	r.Middleware.Next()

	if r.Response.BufferLength() > 0 {
		return
	}

	code, msg, data := parseResponse(r)
	if data == nil {
		data = []string{}
	}

	r.Response.WriteJson(ghttp.DefaultHandlerResponse{
		Code:    code,
		Message: msg,
		Data:    data,
	})
}

func parseResponse(r *ghttp.Request) (int, string, interface{}) {
	var (
		err  = r.GetError()
		code = gerror.Code(err)
	)

	if err != nil {
		if code.Code() == -1 {
			code = errors.CodeServerError
		}
		return code.Code(), err.Error(), nil
	}

	if r.Response.Status > 0 && r.Response.Status != http.StatusOK {
		return r.Response.Status, http.StatusText(r.Response.Status), nil
	}

	code = errors.CodeSuccess
	return code.Code(), code.Message(), r.GetHandlerResponse()
}
